package com.polaris.live.ui.party.widget.seat

import com.polaris.live.common.util.LogExt
import com.polaris.live.ui.party.widget.seat.listener.StreamManageListener
import com.polaris.live.utils.zego.LiveEngineManage
import com.polaris.live.utils.zego.PublishingStreamProxy
import im.zego.zegoexpress.ZegoExpressEngine
import im.zego.zegoexpress.callback.IZegoEventHandler
import im.zego.zegoexpress.constants.ZegoStreamResourceMode
import im.zego.zegoexpress.entity.ZegoPlayerConfig
import java.util.concurrent.ConcurrentHashMap


/**
 *  聊天室流管理
 * @author Created by 天晴 on 2024/2/29 19:17
 * @since 1.0.0
 **/
class PartyStreamProxy {
    companion object {

        const val TAG = "PartyStreamProxy"

    }

    var mStreamManageListener: StreamManageListener? = null
    private val eventHandler = object : IZegoEventHandler() {
        /**
         * 自己本地监听音浪
         */
        override fun onCapturedSoundLevelUpdate(soundLevel: Float) {
            super.onCapturedSoundLevelUpdate(soundLevel)
            mStreamManageListener?.onCapturedSoundLevelUpdate(soundLevel)
        }

        /**
         * 远端拉流音频声浪回调
         *
         * 回调通知周期为 100 ms。
         * @param soundLevels 远端的声浪键值对，key 为流 ID，value 为对应的流的声浪值，value 取值范围为 0.0 ~ 100.0
         */
        override fun onRemoteSoundLevelUpdate(soundLevels: HashMap<String, Float>?) {
            super.onRemoteSoundLevelUpdate(soundLevels)
            soundLevels?.let {
                soundLevels.forEach { map ->
                    getKeyFromValue(playingList, map.key)?.let { seatId ->
                        mStreamManageListener?.onRemoteSoundLevelUpdate(seatId, map.value)
                    }

                }
            }
        }

    }

    fun <K, V> getKeyFromValue(map: Map<K, V>, value: V): K? {
        for ((key, value1) in map.entries) {
            if (value == value1) {
                return key
            }
        }
        return null
    }

    var engine: ZegoExpressEngine? = null


    /**
     * 加入房间添加回调
     */
    fun setJoinRoom(mStreamManageListener: StreamManageListener) {
        engine = LiveEngineManage.getEngine()
        this.mStreamManageListener = mStreamManageListener
        LiveEngineManage.eventHandlerHelper.addEventHandler(eventHandler)
        //启动监听声浪
        engine?.startSoundLevelMonitor(500)
        LogExt.logI(TAG,"setJoinRoom==========")
    }


    /**
     * 播放中的流
     */
    val playingList = ConcurrentHashMap<Int, String>()


    /**
     * 开启流
     */
    fun openStream(seatId: Int, streamId: String) {
        val mStreamId = playingList[seatId]
        if (mStreamId == null) {
            startStream(streamId)
            playingList[seatId] = streamId
        } else {
            //流ID不一样切换
            if (streamId != mStreamId) {
                closeStreamsBySeatId(seatId)
                startStream(streamId)
                playingList[seatId] = streamId
            }
        }
        LogExt.logI(TAG,"openStream==========seatId:$seatId  streamId:$streamId")
    }


    private fun startStream(streamId: String) {
        val playerConfig = ZegoPlayerConfig().apply {
            resourceMode = ZegoStreamResourceMode.ONLY_L3
        }
        engine?.startPlayingStream(streamId, playerConfig)
        LogExt.logI(TAG,"startStream==========  streamId:$streamId")
    }

    /**
     * 将指定位置上得流关闭
     */
    fun closeStreamsBySeatId(seatId: Int) {
        playingList[seatId]?.let {
            engine?.stopPlayingStream(it)
        }
        playingList.remove(seatId)
        LogExt.logI(TAG,"closeStreamsBySeatId==========  seatId:$seatId")
    }


    /**
     * 清除全部流
     */
    fun clearStreams() {
        playingList.forEach { a ->
            engine?.stopPlayingStream(a.value)
        }
        playingList.clear()
        LogExt.logI(TAG,"clearStreams========== ")
    }

    var streamId: String? = null

    /**
     *
     * 发布自己的流
     */
    fun publishStream(streamId: String) {
        if (this.streamId != streamId) {
            stopPublishStream()
            PublishingStreamProxy.start(hashCode(), streamId) {
                if (it) {
                    engine?.muteMicrophone(false)
                    engine?.enableCamera(false)

                    engine?.startPreview()
                    engine?.startPublishingStream(streamId)
                    this.streamId = streamId
                }
            }

        }
        LogExt.logI(TAG,"publishStream========== streamId:$streamId")
    }


    /**
     *
     * 停止发布自己的流
     */
    fun stopPublishStream() {
        LogExt.logI(TAG,"stopPublishStream========== streamId:$streamId")
        PublishingStreamProxy.checkState(hashCode(), streamId) {
            if (it) {
                engine?.enableCamera(false)
                engine?.muteMicrophone(true)
                streamId?.let {
                    engine?.stopPreview()
                    engine?.stopPublishingStream()
                }
            }
        }
        streamId = null

    }


    fun destroyStreams() {
        // 停止监听声浪
        engine?.stopSoundLevelMonitor();
        LiveEngineManage.eventHandlerHelper.removeEventHandler(eventHandler)
        stopPublishStream()
        clearStreams()
        engine = null
        LogExt.logI(TAG,"destroyStreams========== ")
    }



}